import java.nio.channels.FileChannel;


public class db_reading_glass {
	private long lPos = 0;
	private long lGroup = 0;
	private FileChannel oChannel = null;
	private db_book oBook = null;
	private db_transaction oTransaction;
	
	public long position() {
		return lPos;
	}
	
	db_reading_glass(db_book oBookPointer, FileChannel oCh) {
		oBook = oBookPointer;
		oChannel = oCh;
	}
	public void begin() {
		oTransaction = oBook.begin();
	}
	
	public void rollback() {
		oBook.rollback(oTransaction);
	}
	
	public void commit() {
		oBook.commit(oTransaction, oChannel);
	}
	
	public void seekGroup(long lGroupVal) {
		lPos = 0;
		lGroup = lGroupVal;
	}
	public void writeBytes(byte[] oBytes) {
		oBook.write(lGroup, lPos, oBytes, oChannel, oTransaction);
		lPos += oBytes.length;
	}
	
	public byte[] readBytes(int iLen) {
		byte[] oBytes = oBook.read(lGroup, lPos, iLen, oChannel);
		lPos += (long)iLen;
		return oBytes;
	}
	
	public void writeStr(String sStr) {
		db_bytes oBytes = new db_bytes(sStr.length() + 4);
		oBytes.write(intToByteArray(sStr.length()));
		oBytes.write(sStr.getBytes());
		oBook.write(lGroup, lPos, oBytes.getBytes(), oChannel, oTransaction);
		lPos += sStr.length() + 4;
	}


		
	public void writeStr(String sStr, int iFrameLength) {
		db_bytes oBytes = new db_bytes(sStr.length() + 4);
		oBytes.write(intToByteArray(sStr.length()));
		oBytes.write(sStr.getBytes());
		oBook.write(lGroup, lPos, oBytes.getBytes(), oChannel, oTransaction);
		lPos += iFrameLength + 4;
	}
	
	public String readStr() {
		int iLen = byteArrayToInt(oBook.read(lGroup, lPos, 4, oChannel));
		lPos += 4;
		String sStr = new String(oBook.read(lGroup, lPos, iLen, oChannel));
		lPos += iLen;
		return sStr;
	}
	public int groupCount() {
		return oBook.groupCount();
	}
	public int createGroup() {
		return oBook.createGroup();
	}
	public String readStr(int iLength) {
		byte[] bBytes = oBook.read(lGroup, lPos, 4, oChannel);
		int iLen = byteArrayToInt(bBytes);
		lPos += 4;
		String sStr = new String(oBook.read(lGroup, lPos, iLen, oChannel));

		lPos += iLength;
		return sStr;
	}
	
	
	public void seek(long lPosition) {
		lPos = lPosition;
	}
	
	public long readLong(){
		long lVal = 0;
		lVal = byteArrayToLong(oBook.read(lGroup, lPos, 8, oChannel));
		lPos += 8;
		return lVal;
	}
	
	public int readInt(){
		int iVal = 0;
		iVal = byteArrayToInt(oBook.read(lGroup, lPos, 4, oChannel));
		lPos += 4;
		return iVal;
	}
	
	public void writeLong(long lVal) {
		oBook.write(lGroup, lPos, longToByteArray(lVal), oChannel, oTransaction);
		lPos += 8;
	}
	
	public void writeInt(int iVal) {
		oBook.write(lGroup, lPos, intToByteArray(iVal), oChannel, oTransaction);
		lPos += 4;
	}
	
	public long length() {
		return oBook.length(lGroup, oChannel);
	}
	
	public static final int byteArrayToInt(byte [] b) {
		return (b[0] << 24)
		+ ((b[1] & 0xFF) << 16)
		+ ((b[2] & 0xFF) << 8)
		+ (b[3] & 0xFF);
	}
	
	public static final byte[] intToByteArray(int value) {
        return new byte[] {
                (byte)(value >>> 24),
                (byte)(value >>> 16),
                (byte)(value >>> 8),
                (byte)value};
	}
	
	public static final long byteArrayToLong(byte [] b) {
		return ((long)b[0] << 56)
		+ (((long)b[1] & 0xFF) << 48)
		+ (((long)b[2] & 0xFF) << 40)
		+ (((long)b[3] & 0xFF) << 32)
		+ (((long)b[4] & 0xFF) << 24)
		+ (((long)b[5] & 0xFF) << 16)
		+ (((long)b[6] & 0xFF) << 8)
		+ ((long)b[7] & 0xFF);
	}
	public static final byte[] longToByteArray(long value) {
        return new byte[] {
                (byte)(value >>> 56),
                (byte)(value >>> 48),
                (byte)(value >>> 40),
                (byte)(value >>> 32),
                (byte)(value >>> 24),
                (byte)(value >>> 16),
                (byte)(value >>> 8),
                (byte)value};
	}
}
